/***********************
Program:	Flexi
Author:		Bejan Ghomashi
Purpose:	Main entry into the program.
			Initializes the Taskmanager,
			then begins basic system tasks.

			Initialized Objects:
			-FlexiApplication	- main application loop
			-Settings			- reads out of program data
			-Renderer			- screen output / window manager
			-TaskManager		- parent task
			-Library			- memory for all resources
			-Game				- application (de)initializer
***********************/

#include <iostream>
#include "FlexiApplication.h"
#include "OpenGLRenderer.h"
#include "TaskManager.h"
#include "Library.h"
#include "Settings.h"
#include "GlobalTimer.h"
#include "RenderTask.h"
#include "Game.h"

void InitializeRenderSettings()
{
	Settings::getSingleton().RegisterVariable("ShadeModel", new CDator<unsigned int>(Renderer->getShadeModel()));
	Settings::getSingleton().RegisterVariable("ClearColor", new CDatorVector<float>(Renderer->getClearColor()));
	Settings::getSingleton().RegisterVariable("ClearDepth", new CDator<float>(Renderer->getClearDepthValue()));
	Settings::getSingleton().RegisterVariable("DepthTest", new CDator<bool>(Renderer->getDepthTest()));
	Settings::getSingleton().RegisterVariable("DepthFunction", new CDator<unsigned int>(Renderer->getDepthFunc()));
	Settings::getSingleton().RegisterVariable("Hints", new CDatorVector<unsigned int>(Renderer->getHints()));
	Settings::getSingleton().RegisterVariable("WindowTitle", new CDator<std::string>(Renderer->getWindowTitle()));
	Settings::getSingleton().RegisterVariable("WindowWidth", new CDator<unsigned int>(Renderer->getWindowWidth()));
	Settings::getSingleton().RegisterVariable("WindowHeight", new CDator<unsigned int>(Renderer->getWindowHeight()));
}

int main()
{
	// Create
	new Game();
	new FlexiApplication();
	new Settings();
	new OpenGLRenderer();
	new TaskManager();
	new Library();
	
	// Init
	InitializeRenderSettings();

	Settings::getSingleton().ParseFile("Settings.txt");

	FlexiApplication::getSingleton().timer = Pointer<ITask>(new GlobalTimer());
	FlexiApplication::getSingleton().renderer = Pointer<ITask>(new RenderTask());
	
	TaskManager::getSingleton().AddTask(FlexiApplication::getSingleton().timer);
	TaskManager::getSingleton().AddTask(FlexiApplication::getSingleton().renderer);
	
	// Run!
	Game::getSingleton().Initialize();
	TaskManager::getSingleton().Execute();
	Game::getSingleton().Deinitialize();

	// Delete
	delete Library::getSingletonPtr();
	delete TaskManager::getSingletonPtr();
	delete Settings::getSingletonPtr();
	delete FlexiApplication::getSingletonPtr();
	delete Game::getSingletonPtr();
}